package com.ruoyi.web.controller.robot;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.framework.web.domain.server.Mem;
import com.ruoyi.system.domain.*;
import com.ruoyi.system.domain.vo.*;
import com.ruoyi.system.service.*;
import com.ruoyi.system.service.impl.OtherRobotAdminServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.*;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.validation.constraints.NotNull;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 群房间
 */
@RestController
@RequestMapping("/robot/roomconfig")
public class RobotRoomJobConfigController extends BaseController {

    @Resource
    private IOtherRobotRoomJobConfigService otherRobotRoomJobConfigService;
    @Autowired
    private OtherRobotAdminServiceImpl otherRobotAdminServiceImpl;

    @Resource
    private IOtherRobotInfoService otherRobotInfoService;
    @Autowired
    private IRobotWechatUserService robotWechatUserService;

    @Resource
    private IOtherTakeLeaveService otherTakeLeaveService;

    @Resource
    private IOtherRoomEventConfigService otherRoomEventConfigService;

    @Resource
    private IOtherBlockedRecordService otherBlockedRecordService;

    @Resource
    private IOthertoptaskConfigService othertoptaskConfigService;

    @Resource
    private IOtherRoundPeriodConfigService otherRoundPeriodConfigService;

    /**
     * 机器人服务器地址
     */
//    @Value(value = "${robot.url}")
//    private String robotUrl;
    @Resource
    private RestTemplate restTemplate;


    Map<String, String> roomAndURL = Collections.synchronizedMap(new HashMap<String, String>());

    /**
     * 初始化数据
     */
    @PostConstruct
    private void init() {
        List<OtherRoomJobConfig> depts = otherRobotRoomJobConfigService.selectRoomJobConfigList();
        depts.forEach(otherRoomJobConfig -> {
            OtherRobotInfo otherRobotInfo = otherRobotInfoService.selectOtherRobotInfo(otherRoomJobConfig.getRobotWx());
            if (otherRobotInfo == null) {
                return;
            }
            roomAndURL.put(otherRoomJobConfig.getRoomID(), otherRobotInfo.getBackEndAddress());
        });
    }


    /**
     * 列出群列表
     *
     * @return
     */
    @GetMapping("/list")
    public AjaxResult list() {
        List<OtherRoomJobConfig> depts = otherRobotRoomJobConfigService.selectRoomJobConfigList();
        return success(depts);
    }


    public String getUrl(String roomID) {
        String url = roomAndURL.get(roomID);
        //说明是新增群
        if (url == null) {
            logger.warn("getUrl  roomAndURL == null" + roomID);
            OtherRoomJobConfig otherRoomJobConfig = otherRobotRoomJobConfigService.selectRoomJobConfigByRoomId(roomID);
            if (otherRoomJobConfig == null) {
                logger.error("getUrl  otherRoomJobConfig == null" + roomID);
                return null;
            }
            OtherRobotInfo otherRobotInfo = otherRobotInfoService.selectOtherRobotInfo(otherRoomJobConfig.getRobotWx());
            if (otherRobotInfo == null) {
                logger.error("getUrl  otherRobotInfo == null" + otherRoomJobConfig.getRobotWx() + roomID);
                return null;
            }
            roomAndURL.put(otherRoomJobConfig.getRoomID(), otherRobotInfo.getBackEndAddress());
            return roomAndURL.get(roomID);
        } else {
            return url;
        }
    }


    public Map<String, Map<String, String>> getRoomMember(String roomId) {
        logger.info("getRoomMember start" + roomId);
        String url = "http://" + getUrl(roomId) + "/getAllRoomMembers";
        HttpRobotMemberInfo robotMemberInfo = new HttpRobotMemberInfo();
        robotMemberInfo.setRoomID(roomId);
        ResponseEntity<HttpMemberInfoRsp> response = restTemplate.postForEntity(url, robotMemberInfo, HttpMemberInfoRsp.class);
        Map<String, Map<String, String>> rsp = new HashMap();
        String jsonString = response.getBody().getMessage();
        ObjectMapper mapper = new ObjectMapper();
        try {
            rsp = (Map<String, Map<String, String>>) mapper.readValue(jsonString, Map.class);

        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
        logger.info("getRoomMember end" + roomId);
        return rsp;
    }

    /**
     * 获取用户群绑定群列表
     *
     * @param openid
     * @return
     */
    @GetMapping("/userRoomList")
    public AjaxResult userRoomList(String openid) {
        List<MemberRobotRoomsRspVo> memberRobotRoomsRspVos = new ArrayList<>();
        RobotWechatUser userPasswordCommand = robotWechatUserService.getUserPasswordCommand(openid);
        if (userPasswordCommand.getPasswordCommand() == null || userPasswordCommand.getPasswordCommand().equals("")) {
            return success(memberRobotRoomsRspVos);
        }


//        logger.info(roomInfo.toString());

        //找出用户所有的群id
        List<OtherRobotAdmin> otherRobotAdmins = otherRobotAdminServiceImpl.getOtherRobotAdmin(userPasswordCommand.getPasswordCommand());
        if (otherRobotAdmins.isEmpty()) {
            return success(memberRobotRoomsRspVos);
        }

        List<String> roomIDs = otherRobotAdmins.stream().map(OtherRobotAdmin::getRoomID).toList();
        if (roomIDs.isEmpty()) {
            return success(memberRobotRoomsRspVos);
        }
        List<OtherRoomJobConfig> otherRoomJobConfigsList = otherRobotRoomJobConfigService.selectRoomJobConfigByRoomIdS(roomIDs);

        List<String> robotWxs = otherRoomJobConfigsList.stream().map(OtherRoomJobConfig::getRobotWx).toList();
        if (robotWxs.isEmpty()) {
            return success(memberRobotRoomsRspVos);
        }

        List<OtherRobotInfo> otherRobotInfoList = otherRobotInfoService.selectOtherRobotInfoBywxids(robotWxs);

        otherRobotAdmins.forEach(otherRobotAdmin -> {

            List<OtherRoomJobConfig> otherRoomJobConfigs1 = otherRoomJobConfigsList.stream().filter(otherRoomJobConfig -> otherRoomJobConfig.getRoomID().equals(otherRobotAdmin.getRoomID())).toList();

            if (otherRoomJobConfigs1 == null || otherRoomJobConfigs1.isEmpty()) {
                return;
            }
            OtherRoomJobConfig otherRoomJobConfigs = otherRoomJobConfigs1.get(0);
            //过滤状态和截止日期
            if (Objects.equals(otherRoomJobConfigs.getStatus(), "退出群聊") || LocalDateTime.now().isAfter(otherRoomJobConfigs.getEndTime())) {
                return;
            }


            List<OtherRobotInfo> otherRobotInfos = otherRobotInfoList.stream().filter(otherRobotInfo1 -> otherRobotInfo1.getWxid().equals(otherRoomJobConfigs.getRobotWx())).toList();
            if (otherRobotInfos == null || otherRobotInfos.isEmpty()) {
                return;
            }
            OtherRobotInfo otherRobotInfo = otherRobotInfos.get(0);
            if (otherRobotInfo.getBackEndAddress() == null) {
                return;
            }

            MemberRobotRoomsRspVo memberRobotRoomsRspVo = new MemberRobotRoomsRspVo();
            memberRobotRoomsRspVo.setEndTime(otherRoomJobConfigs.getEndTime());
            memberRobotRoomsRspVo.setRobotName(otherRobotInfo.getNickName());
            memberRobotRoomsRspVo.setRoomId(otherRobotAdmin.getRoomID());
            //更新URL
            if (!otherRobotInfo.getBackEndAddress().isEmpty()) {
                roomAndURL.put(otherRobotAdmin.getRoomID(), otherRobotInfo.getBackEndAddress());
            }

            Map<String, HttpRoomInfo> roomInfo = getRoomInfo(otherRobotAdmin.getRoomID());

            HttpRoomInfo httpRoomInfo = roomInfo.get(otherRobotAdmin.getRoomID());
            if (httpRoomInfo != null) {
                if (httpRoomInfo.getNick_name() != null) {
                    memberRobotRoomsRspVo.setRoomName(httpRoomInfo.getNick_name());
                }
                if (httpRoomInfo.getAvatar_url() != null) {
                    memberRobotRoomsRspVo.setImageUrl(httpRoomInfo.getAvatar_url());
                }
            }


            memberRobotRoomsRspVos.add(memberRobotRoomsRspVo);
        });

        Comparator<MemberRobotRoomsRspVo> compare = Comparator.comparing(MemberRobotRoomsRspVo::getEndTime);
        memberRobotRoomsRspVos.sort(compare.reversed());
        return success(memberRobotRoomsRspVos);
    }


    private Map<String, HttpRoomInfo> getRoomInfo(String roomID) {
        String url = "http://" + getUrl(roomID) + "/getAllRooms";
        RestTemplate restTemplate = new RestTemplate();
        StringHttpMessageConverter stringHttpMessageConverter = (StringHttpMessageConverter) restTemplate.getMessageConverters().get(1);
        stringHttpMessageConverter.setDefaultCharset(StandardCharsets.UTF_8);
        String result = null;
        try {
            result = restTemplate.getForObject(url, String.class);
        } catch (RestClientException e) {
            //这里可能是机器人下线了
            return new HashMap<>();
        }
        ObjectMapper mapper = new ObjectMapper();
        HttpRoomInfoRsp httpRoomInfoRsp;
        try {
            httpRoomInfoRsp = mapper.readValue(result, HttpRoomInfoRsp.class);
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
        if (httpRoomInfoRsp.getMessage().getData() == null) {
            logger.info("getRoomInfo 获取直播间信息失败" + roomID);
            return new HashMap<String, HttpRoomInfo>();
        }
        return httpRoomInfoRsp.getMessage().getData().getList().stream().collect(Collectors.toMap(HttpRoomInfo::getWx_id, Function.identity()));
    }

    @PutMapping("/updateRoomConfig")
    public AjaxResult updateRoomConfig(@RequestBody @NotNull HttpUpdateRoomConfig httpUpdateRoomConfig) {
        String url = "http://" + getUrl(httpUpdateRoomConfig.getRoomID()) + "/changeSetting";

        if (httpUpdateRoomConfig.getRoundConfig() != null && httpUpdateRoomConfig.getRoundConfig().getHost() != null) {
            String modifiedString = httpUpdateRoomConfig.getRoundConfig().getHost().replaceAll("[\n\r]+$", "");
            httpUpdateRoomConfig.getRoundConfig().setHost(modifiedString);
        }

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        HttpEntity<HttpUpdateRoomConfig> entity = new HttpEntity<>(httpUpdateRoomConfig, headers);

        ResponseEntity<HttpMemberInfoRsp> httpMemberInfoRspResponseEntity = this.restTemplate.postForEntity(url, entity, HttpMemberInfoRsp.class);
        return httpMemberInfoRspResponseEntity.getBody().getStatus() == 200 ? AjaxResult.success() : AjaxResult.error();
    }


    /**
     * 通过roomid 查询群
     *
     * @param roomId
     * @return
     */
    @GetMapping("/roomId")
    public AjaxResult roomId(String roomId) {
        OtherRoomJobConfig otherRoomJobConfigs = otherRobotRoomJobConfigService.selectRoomJobConfigByRoomId(roomId);
        return success(otherRoomJobConfigs);
    }


    /**
     * 更新配置
     *
     * @param otherRoomJobConfig
     * @return
     */
    @PostMapping("/updateInfo")
    public AjaxResult updateInfo(@RequestBody OtherRobotUpdateReqVo otherRoomJobConfig) {
        return success(otherRobotRoomJobConfigService.updateRoomJobConfig(otherRoomJobConfig));
    }


    /**
     * 通过roomid 查询群
     *
     * @param roomId
     * @return
     */
    @GetMapping("/eventConfigroomId")
    public AjaxResult getRoomEventConfigByRoomId(String roomId) {
        OtherRoomEventConfig otherRoomJobConfigs = otherRoomEventConfigService.getRoomEventConfigByRoomId(roomId);
        return success(otherRoomJobConfigs);
    }

    @PutMapping("/eventConfigrupdate")
    public AjaxResult updateRoomEventConfigByRoomId(@RequestBody OtherRoomEventConfig otherRoomEventConfig) {
        int rsp = otherRoomEventConfigService.updateRoomEventConfigByRoomId(otherRoomEventConfig);
        return rsp > 0 ? AjaxResult.success() : AjaxResult.error();
    }

    @GetMapping("/takeLeaveroomId")
    public AjaxResult getTakeLeaveConfigByRoomId(String roomId) {
        OtherTakeLeaveConfig otherRoomJobConfigs = otherTakeLeaveService.getTakeLeaveConfigByRoomID(roomId);
        return success(otherRoomJobConfigs);
    }

    @PutMapping("takeLeaverupdate")
    public AjaxResult updateTakeLeaveConfig(@RequestBody OtherTakeLeaveConfig otherRoomJobConfig) {
        int rsp = otherTakeLeaveService.updateTakeLeaveConfigByRoomID(otherRoomJobConfig);
        return rsp > 0 ? AjaxResult.success() : AjaxResult.error();
    }

    @GetMapping("/balockedRecordroomId")
    public AjaxResult getBlockRecordByRoomId(String roomId) {
        return success(otherBlockedRecordService.getOtherBlockedRecord(roomId));
    }

    @DeleteMapping("/balockedRecordId")
    public AjaxResult deleteBlockRecordById(Long id) {
        int rsp = otherBlockedRecordService.deleteOtherBlockedRecord(id);
        return rsp > 0 ? AjaxResult.success(rsp) : AjaxResult.error();
    }

    @GetMapping("/toptaskroomId")
    public AjaxResult getTopTakByRoomId(String roomId) {
        return success(othertoptaskConfigService.getOthertoptaskConfigList(roomId));
    }

    @PutMapping("toptaskupdate")
    public AjaxResult updateTopTakByRoomId(@RequestBody OthertoptaskConfig othertoptaskConfig) {
        int rsp = othertoptaskConfigService.updateOthertoptaskConfig(othertoptaskConfig);
        return rsp > 0 ? AjaxResult.success(rsp) : AjaxResult.error();
    }

    @GetMapping("/getZcInfoByRoomId")
    public AjaxResult getZcInfoByRoomId(String roomId) {
        return success((Object) otherRoundPeriodConfigService.getZcStr(roomId));
    }

}
